package com.kye.express.business.order.order_address;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.databinding.DataBindingUtil;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.text.SpannableString;
import android.text.TextUtils;
import android.text.style.ForegroundColorSpan;
import android.view.Menu;
import android.view.MenuItem;

import com.jakewharton.rxbinding2.support.v7.widget.RxToolbar;
import com.jakewharton.rxbinding2.view.RxView;
import com.jakewharton.rxbinding2.widget.RxTextView;
import com.kye.addrpicker.AddressPickerActivity;
import com.kye.addrpicker.model.AddressPickerResult;
import com.kye.base.DebounceObservableTransformer;
import com.kye.express.R;
import com.kye.express.business.base.BaseAppCompatActivity;
import com.kye.express.databinding.ActivityAddressEditBinding;
import com.kye.express.utils.ToolbarManager;
import com.kye.express.view.KyeProgressDialog;
import com.kye.express.view.ToastManager;
import com.kye.model.bean.order.OrderAddresses;

import io.reactivex.Observable;
import io.reactivex.functions.BiFunction;
import io.reactivex.functions.Consumer;
import io.reactivex.functions.Function5;
import io.reactivex.functions.Predicate;

public class AddressEditActivity extends BaseAppCompatActivity implements AddressEditContract.AddressEditView {

    private static final String KEY_COMPANY = "KEY_COMPANY";
    private static final String KEY_ADDRESS = "KEY_ADDRESS";
    public static final int ADDRESS_EDIT_ACTIVITY_REQUEST_CODE = 1;

    private ActivityAddressEditBinding mBinding;
    private Mode mMode;
    private AddressEditContract.AddressEditPresenter mPresenter;
    private Dialog mDialog;

    public static void startActivityForResult(Activity activity, OrderAddresses orderAddresses) {
        activity.startActivityForResult(
                new Intent(activity, AddressEditActivity.class)
                        .putExtra(KEY_COMPANY, orderAddresses),
                ADDRESS_EDIT_ACTIVITY_REQUEST_CODE
        );
    }

    public static void startActivityForResult(Activity activity, OrderAddresses.Address item) {
        activity.startActivityForResult(
                new Intent(activity, AddressEditActivity.class)
                        .putExtra(KEY_ADDRESS, item),
                ADDRESS_EDIT_ACTIVITY_REQUEST_CODE
        );
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_address_edit);

        initEvent();
        initData();
    }

    private void initEvent() {
        ToolbarManager.setToolbar(this, mBinding.toolbar);

        RxToolbar.itemClicks(mBinding.toolbar)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<MenuItem>() {
                    @Override
                    public void accept(MenuItem menuItem) throws Exception {
                        mPresenter.deleteTempAddress(mBinding.getAddress().getGuid());
                    }
                });

        RxView.clicks(mBinding.linearLayoutAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        AddressPickerActivity.startActivityForResult(AddressEditActivity.this, "选择地址", AddressPickerActivity.Levels.area);
                    }
                });

        Observable<CharSequence> editTextAddressName = RxTextView.textChanges(mBinding.editTextAddressName).cache();
        Observable<CharSequence> editTextDetailAddress = RxTextView.textChanges(mBinding.editTextDetailAddress).cache();
        Observable<CharSequence> editTextPerson = RxTextView.textChanges(mBinding.editTextPerson).cache();
        Observable<CharSequence> editTextPhone = RxTextView.textChanges(mBinding.editTextPhone).cache();

        RxView.clicks(mBinding.buttonSaveAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .filter(new Predicate<Object>() {
                    @Override
                    public boolean test(Object o) throws Exception {
                        return mMode == Mode.editAddress;
                    }
                });
        Observable.combineLatest(editTextAddressName, editTextDetailAddress, editTextPerson, editTextPhone, RxTextView.textChanges(mBinding.textViewAddress), new Function5<CharSequence, CharSequence, CharSequence, CharSequence, CharSequence, Boolean>() {
            @Override
            public Boolean apply(CharSequence charSequence, CharSequence charSequence2, CharSequence charSequence3, CharSequence charSequence4,CharSequence charSequence5) throws Exception {
                return
                        !TextUtils.isEmpty(charSequence) &&
                                !TextUtils.isEmpty(charSequence2) &&
                                !TextUtils.isEmpty(charSequence3) &&
                                !TextUtils.isEmpty(charSequence4) &&
                                !TextUtils.isEmpty(charSequence5);
            }
        })
                .filter(new Predicate<Boolean>() {
                    @Override
                    public boolean test(Boolean aBoolean) throws Exception {
                        return mMode == Mode.addTempAddress || mMode == Mode.editTempAddress;
                    }
                })
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        mBinding.buttonSaveAddress.setEnabled(aBoolean);
                    }
                });

        Observable.combineLatest(editTextPerson, editTextPhone, new BiFunction<CharSequence, CharSequence, Boolean>() {
            @Override
            public Boolean apply(CharSequence charSequence, CharSequence charSequence2) throws Exception {
                return !TextUtils.isEmpty(charSequence) &&
                        !TextUtils.isEmpty(charSequence2);
            }
        })
                .filter(new Predicate<Boolean>() {
                    @Override
                    public boolean test(Boolean aBoolean) throws Exception {
                        return mMode == Mode.editAddress;
                    }
                })
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Boolean>() {
                    @Override
                    public void accept(Boolean aBoolean) throws Exception {
                        mBinding.buttonSaveAddress.setEnabled(aBoolean);
                    }
                });

        RxView.clicks(mBinding.buttonSaveAddress)
                .compose(new DebounceObservableTransformer<>())
                .compose(bindToLifecycle())
                .subscribe(new Consumer<Object>() {
                    @Override
                    public void accept(Object o) throws Exception {
                        switch (mMode) {
                            case editAddress:
                                mPresenter.editTempAddress(
                                        mBinding.getAddress().getAddressName(),
                                        mBinding.getAddress().getProvince(),
                                        mBinding.getAddress().getCity(),
                                        mBinding.getAddress().getCounty(),
                                        mBinding.getAddress().getDetailsAddress(),
                                        mBinding.editTextPerson.getText().toString().trim(),
                                        mBinding.editTextPhone.getText().toString().trim(),
                                        mBinding.editTextNumber.getText().toString().trim(),
                                        mBinding.getAddress().getGuid(),
                                        mBinding.getAddress().getCompanyCode()
                                );
                                break;
                            case addTempAddress:
                                mPresenter.addTempAddress(
                                        mBinding.editTextAddressName.getText().toString().trim(),
                                        mBinding.getProvince(),
                                        mBinding.getCity(),
                                        mBinding.getCounty(),
                                        mBinding.editTextDetailAddress.getText().toString().trim(),
                                        mBinding.editTextPerson.getText().toString().trim(),
                                        mBinding.editTextPhone.getText().toString().trim(),
                                        mBinding.editTextNumber.getText().toString().trim(),
                                        mBinding.getCompany().getCompanyCode(),
                                        mBinding.getCompany().getCompanyName()
                                );
                                break;
                            case editTempAddress:
                                mPresenter.editTempAddress(
                                        mBinding.editTextAddressName.getText().toString().trim(),
                                        mBinding.getProvince(),
                                        mBinding.getCity(),
                                        mBinding.getCounty(),
                                        mBinding.editTextDetailAddress.getText().toString().trim(),
                                        mBinding.editTextPerson.getText().toString().trim(),
                                        mBinding.editTextPhone.getText().toString().trim(),
                                        mBinding.editTextNumber.getText().toString().trim(),
                                        mBinding.getAddress().getGuid(),
                                        mBinding.getAddress().getCompanyCode()
                                );
                                break;
                        }
                    }
                });
    }

    private void initData() {
        mBinding.setCompany((OrderAddresses) getIntent().getSerializableExtra(KEY_COMPANY));
        OrderAddresses.Address address = (OrderAddresses.Address) getIntent().getSerializableExtra(KEY_ADDRESS);
        mBinding.setAddress(address);

        if (address != null) {
            mBinding.setProvince(address.getProvince());
            mBinding.setCity(address.getCity());
            mBinding.setCounty(address.getCounty());
        }

        if (mBinding.getCompany() != null) {
            setTitle("新增临时地址");
            mMode = Mode.addTempAddress;
        }
        if (mBinding.getAddress() != null) {
            if (mBinding.getAddress().isDefault()) {
                setTitle("默认地址编辑");
                mMode = Mode.editAddress;
            } else {
                setTitle("临时地址编辑");
                mMode = Mode.editTempAddress;
            }
        }

        mPresenter = new AddressEditContract.AddressEditPresenter();
        mPresenter.bind(this);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        if (mMode == Mode.editTempAddress) {
            getMenuInflater().inflate(R.menu.menu_address_edit, menu);
            for (int i = 0; i < menu.size(); i++) {
                MenuItem item = menu.getItem(i);
                int itemId = item.getItemId();
                if (itemId == R.id.menu_delete) {
                    SpannableString s = new SpannableString(item.getTitle().toString().trim());
                    s.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.red_ff6262)), 0, s.length(), 0);
                    item.setTitle(s);
                }
            }
        }
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == AddressPickerActivity.ADDRESS_PICKER_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK && data != null) {
            AddressPickerResult resultAddress = (AddressPickerResult) data.getSerializableExtra(AddressPickerActivity.KEY_ARG_PICKED_RESULT);
            mBinding.setProvince(resultAddress.getProvince());
            mBinding.setCity(resultAddress.getCity());
            mBinding.setCounty(resultAddress.getArea());
        }
    }

    @Override
    public void onError() {
        ToastManager.show(this, R.string.common_net_error);
    }

    @Override
    public void onError(String msg) {
        ToastManager.show(this, msg);
    }

    @Override
    public void onLoading() {
        mDialog = KyeProgressDialog.show(this, mDialog);
    }

    @Override
    public void onLoaded() {
        KyeProgressDialog.dismiss(mDialog);
    }

    @Override
    public void onSuccess() {
        setResult(RESULT_OK);
        finish();
    }

    enum Mode {
        addTempAddress,
        editTempAddress,
        editAddress
    }
}
